/**
 * 
 */
package ai;

import java.util.LinkedList;

/**
 * @author bernard
 *
 */
public abstract class BlindAgent implements Search {
	
	/**
	 * Holds which position is it.
	 */
	Node currentNode = null;
	
	/**
	 * Holds the initial node which contains initial state.
	 */
	Node rootNode = null;
	
	/**
	 * Holds a representation of the target state that we are looking for.
	 */
	State targetSts = null; 

	/**
	 * Holds the not expanded nodes in the fringe
	 */
	LinkedList<Node> fringe = new LinkedList<Node>();
	
	int maxEpsilon = 0;

	public BlindAgent(State initSt, int maxEpsilon) {
		if ( 0 <= maxEpsilon){
			throw new Error("Can'r create Blid agent. Epsilon must be greater than zero.");
		}
		this.maxEpsilon = maxEpsilon;
		this.rootNode = new Node(initSt);
	}

	@Override
	public Node nextFromFinge() {
		return this.fringe.getLast();
		
	}
	

	public void sense(Node node) {
		if (null != node){
			this.currentNode = node;
		}
	}
	
	/**
	 * Returns true if goal state has been reached
	 * @param sts
	 * @return
	 */
	public boolean isGoal(State sts) {
		if(this.targetSts.equals(this.currentNode.getState()) ){
			return true;
		}
		return false;
	}
	
	
	public void doSearch(State target) throws Exception{
		//get current node
		
		targetSts = target;
		
		fringe.add(rootNode);
		
		while(true){
			currentNode = nextFromFinge();
			if (currentNode.getState() == targetSts){
				//return retrivePath(n, path)
			}
			for (Node nodeElem : rootNode.expand(rootNode)){
				fringe.add(nodeElem);
			}			
		}
	}
	
	/**
	 * Retrieves the path from current node until root is reached 
	 * @param n Node from which we returned  the path, 
	 * @param path
	 * @return
	 */
	public LinkedList<Action> retrivePath(Node n, LinkedList<Action> path){
		
		LinkedList<Action> solution = new LinkedList<Action>();
		
		if (n == rootNode){
			return solution;
		}
		else{
			solution.add(n.getAction());
			solution.addAll(retrivePath(n.getParent(), solution));
		}
		return solution;
	}
	
}
